(ns tala.test.core
  (:use tala.core)
  (:use clojure.test))

;; First, some handy functions
(defn- get-response-header [resp header]
  (get-in resp [:headers header]))
(defn- get-content-type [resp]
  (get-response-header resp "Content-Type"))

(defn- consume-inputstream [^java.io.InputStream is]
  "Consume the lines of a string into a sequence of strings (hmm: skips newlines)"
  (reduce (fn [s line]
            (str s "\n" line))
          ""
          (line-seq (java.io.BufferedReader. (java.io.InputStreamReader. is)))))


;; Correct response from bad URL
(deftest handle-catchall
  (let [resp (handler {:uri "/foo" :request-method :get})]
    (is (= 404 (:status resp)))))

;; The following URL tests also test the functions in info.clj
(deftest handle-tagged-object
  (let [resp (handler {:uri "/tag/weird" :request-method :get})]
    (is (= 200 (:status resp)))
    (is (= "text/html" (get-content-type resp)))
    (is (re-find #"<li>" (:body resp))))) ;there are more sophisticated tests...
(deftest handle-tagged-object-per-user
  (let [resp (handler {:uri "/u/norman@astro.gla.ac.uk/weird" :request-method :get})]
    (is (= 200 (:status resp)))
    (is (= "text/html" (get-content-type resp)))
    (is (re-find #"<li>" (:body resp)))))

;; Describe users
(deftest describe-user-id-no-accept
  (let [resp (handler {:uri "/id/u/norman@astro.gla.ac.uk" :request-method :get})]
    (is (= 406 (:status resp)))))
(deftest describe-user-id-html
  (let [resp (handler {:uri "/id/u/norman@astro.gla.ac.uk"
                       :request-method :get
                       :headers {"accept" "text/html"}})]
    (is (= 303 (:status resp)))
    (is (= "/u/norman@astro.gla.ac.uk"
           (get-response-header resp "Location")))))
(deftest describe-user-id-rdfxml
  (let [resp (handler {:uri "/id/u/norman@astro.gla.ac.uk"
                       :request-method :get
                       :headers {"accept" "application/rdf+xml"}})]
    (is (= 303 (:status resp)))
    (is (= "/data/u/norman@astro.gla.ac.uk"
           (get-response-header resp "Location")))))
(deftest describe-user-id-turtle
  (let [resp (handler {:uri "/id/u/norman@astro.gla.ac.uk"
                       :request-method :get
                       :headers {"accept" "text/turtle"}})]
    (is (= 303 (:status resp)))
    (is (= "/data/u/norman@astro.gla.ac.uk"
           (get-response-header resp "Location")))))

(deftest describe-user-html
  (let [resp (handler {:uri "/u/norman@astro.gla.ac.uk"
                       :request-method :get
                       :headers {"accept" "text/html"}})]
    (is (= 200 (:status resp)))
    (is (= "text/html" (get-content-type resp)))
    (is (re-find #"Norman" (:body resp)))))

(deftest describe-user-data-turtle
  (let [resp (handler {:uri "/data/u/norman@astro.gla.ac.uk"
                       :request-method :get
                       :headers {"accept" "text/turtle"}})]
    (is (= 200 (:status resp)))
    (is (= "text/turtle" (get-content-type resp)))
    (is (instance? java.io.InputStream (:body resp)))
    (is (re-find #"a foaf:Person"           ;_slightly_ fragile test, but OK for now
                 (consume-inputstream (:body resp))))))
(deftest describe-user-data-rdfxml
  (let [resp (handler {:uri "/data/u/norman@astro.gla.ac.uk"
                       :request-method :get
                       :headers {"accept" "application/rdf+xml"}})]
    (is (= 200 (:status resp)))
    (is (= "application/rdf+xml" (get-content-type resp)))
    (is (instance? java.io.InputStream (:body resp)))
    (is (re-find #"<foaf:name>Norman</foaf:name>" ;_slightly_ fragile test, but OK for now
                 (consume-inputstream (:body resp))))))
